/*
 * Copyright (c) 2003-2005, National ICT Australia (NICTA)
 */
/*
 * Copyright (c) 2007 Open Kernel Labs, Inc. (Copyright Holder).
 * All rights reserved.
 *
 * 1. Redistribution and use of OKL4 (Software) in source and binary
 * forms, with or without modification, are permitted provided that the
 * following conditions are met:
 *
 *     (a) Redistributions of source code must retain this clause 1
 *         (including paragraphs (a), (b) and (c)), clause 2 and clause 3
 *         (Licence Terms) and the above copyright notice.
 *
 *     (b) Redistributions in binary form must reproduce the above
 *         copyright notice and the Licence Terms in the documentation and/or
 *         other materials provided with the distribution.
 *
 *     (c) Redistributions in any form must be accompanied by information on
 *         how to obtain complete source code for:
 *        (i) the Software; and
 *        (ii) all accompanying software that uses (or is intended to
 *        use) the Software whether directly or indirectly.  Such source
 *        code must:
 *        (iii) either be included in the distribution or be available
 *        for no more than the cost of distribution plus a nominal fee;
 *        and
 *        (iv) be licensed by each relevant holder of copyright under
 *        either the Licence Terms (with an appropriate copyright notice)
 *        or the terms of a licence which is approved by the Open Source
 *        Initative.  For an executable file, "complete source code"
 *        means the source code for all modules it contains and includes
 *        associated build and other files reasonably required to produce
 *        the executable.
 *
 * 2. THIS SOFTWARE IS PROVIDED ``AS IS'' AND, TO THE EXTENT PERMITTED BY
 * LAW, ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 * PURPOSE, OR NON-INFRINGEMENT, ARE DISCLAIMED.  WHERE ANY WARRANTY IS
 * IMPLIED AND IS PREVENTED BY LAW FROM BEING DISCLAIMED THEN TO THE
 * EXTENT PERMISSIBLE BY LAW: (A) THE WARRANTY IS READ DOWN IN FAVOUR OF
 * THE COPYRIGHT HOLDER (AND, IN THE CASE OF A PARTICIPANT, THAT
 * PARTICIPANT) AND (B) ANY LIMITATIONS PERMITTED BY LAW (INCLUDING AS TO
 * THE EXTENT OF THE WARRANTY AND THE REMEDIES AVAILABLE IN THE EVENT OF
 * BREACH) ARE DEEMED PART OF THIS LICENCE IN A FORM MOST FAVOURABLE TO
 * THE COPYRIGHT HOLDER (AND, IN THE CASE OF A PARTICIPANT, THAT
 * PARTICIPANT). IN THE LICENCE TERMS, "PARTICIPANT" INCLUDES EVERY
 * PERSON WHO HAS CONTRIBUTED TO THE SOFTWARE OR WHO HAS BEEN INVOLVED IN
 * THE DISTRIBUTION OR DISSEMINATION OF THE SOFTWARE.
 *
 * 3. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR ANY OTHER PARTICIPANT BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
/*
 * Description:   FASS functions and defines
 */

#ifndef __ARCH__ARM__FASS_H__
#define __ARCH__ARM__FASS_H__

//#include <arch/globals.h>

#define ARM_DOMAINS     16

#define KERNEL_DOMAIN   0
#define INVALID_DOMAIN ARM_DOMAINS

#define PID_AREA_SIZE   MB(32)

#if !defined(ASSEMBLY)

typedef unsigned int arm_domain_t;
typedef unsigned char arm_pid_t;

class space_t;


#define SET_DOMAIN(w,n)  ((w) = (w) | (1 << (n*2)))
#define TEST_DOMAIN(w,n) ((w) & (1 << (n*2)))

INLINE word_t * get_domain_dirty()
{
    return &get_arm_globals()->domain_dirty;
}

INLINE word_t * get_current_domain()
{
    return &get_arm_globals()->current_domain;
}

INLINE word_t * get_current_domain_mask()
{
    return &get_arm_globals()->current_domain_mask;
}

#define domain_dirty        (*get_domain_dirty())
#define current_domain      (*get_current_domain())
#define current_domain_mask (*get_current_domain_mask())

INLINE arm_fass_t * get_arm_fass() PURE;

INLINE arm_fass_t * get_arm_fass()
{
    return get_arm_globals()->arm_fass;
}

typedef unsigned int cpd_bitfield_t;

#define CPD_BITFIELD_WORD_SIZE (8*sizeof(cpd_bitfield_t))
#define CPD_BITFIELD_ARRAY_SIZE ((1 << ARM_SECTION_BITS) /  \
        CPD_BITFIELD_WORD_SIZE)

#define CPD_BITFIELD_POS(section) (section / CPD_BITFIELD_WORD_SIZE)
#define CPD_BITFIELD_OFFSET(section) (section % CPD_BITFIELD_WORD_SIZE)

class arm_fass_t {
public:
    void init(void);
    void clean_all( word_t flush );

    void add_set( arm_domain_t domain, word_t section );
    void remove_set( arm_domain_t domain, word_t section );

    void activate_domain( space_t *space );
    void activate_other_domain( space_t *space );
    void free_domain( space_t *space );

    space_t *get_space( arm_domain_t domain );
    void set_space( arm_domain_t domain, space_t *space );

private:
    int replacement_domain(void);
    arm_domain_t domain_recycle(space_t *space);

private:
    cpd_bitfield_t cpd_set[ARM_DOMAINS][CPD_BITFIELD_ARRAY_SIZE];
    space_t *domain_space[ARM_DOMAINS];
    unsigned int rand;
};

#endif

#endif /* __ARCH__ARM__FASS_H__ */
